package com.seven.smartsnmp.zz;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.Target;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.*;

import java.io.IOException;
import java.util.*;

public class GetDot {
	private Vector<ADT_dot1dTpFdb> vecRet;
	private int MaxRepNum = 20;
	private String communityStr = null;
	
	private String dot1dTpFdbAddress = "1.3.6.1.2.1.17.4.3.1.1";
	private String dot1dTpFdbPort = "1.3.6.1.2.1.17.4.3.1.2";
	private String dot1dTpFdbStatus = "1.3.6.1.2.1.17.4.3.1.3";
	
	private HashMap<String, String> ProcessRaw(String raw, String oriOid)
	{
		String retOid = "";
		String retNeatStr = "";
		HashMap<String, String> hashmap =new HashMap<String, String>();
		
		//�ӻ�ȡ�Ľ���еõ���Ҫ��ֵ
		//���û�л�ȡ��������retOidΪ����һ��oid����һ�μ���ȡ��
		//����ȡ������retOidΪ����
		int beginPos = raw.indexOf("VBS[1.3.6");
		String sub = raw.substring(beginPos+4, raw.length()-2);
		sub = sub + ";";
		boolean hasEnd = false;
		String tmp = null;
		while(sub.length() > 0)
		{
			beginPos = sub.indexOf(";");
			tmp = sub.substring(0, beginPos+1);
			if(tmp.charAt(0) == ' ')
			{
				tmp = tmp.substring(1);
			}
			if(tmp.indexOf(oriOid) == -1)
			{
				hasEnd = true;
				break;
			}else{
				retNeatStr = retNeatStr + tmp;
				if(sub.length() ==  beginPos+1)
				{
					sub = "";
				}else{
					sub = sub.substring(beginPos+1);
				}
			}
		}
		
		
		if(!hasEnd)
		{
			beginPos = tmp.indexOf("=");
			retOid = tmp.substring(0,beginPos-1);
		}
		hashmap.put("oid", retOid);
		hashmap.put("str", retNeatStr);
		return hashmap;
	}
		
	private String GetSingleInfo(Snmp snmp, PDU pdu, String ip, String destOid)
	{
		// ���Ŀ���ַ����
		Address targetAddress = GenericAddress.parse(ip);
		Target target = null;
		target = new CommunityTarget();

		target.setVersion(SnmpConstants.version2c); //һ�㶼�����
		((CommunityTarget) target).setCommunity(new OctetString(communityStr));
		// Ŀ������������
		target.setAddress(targetAddress);
		target.setRetries(5);
		target.setTimeout(1000);
		String RetStr = "";
		String tmp = null;
		//String tmpOid = null;
		HashMap<String, String> tmpMap = null;
		try {
			while(true)
			{
				ResponseEvent response = snmp.send(pdu, target);
				PDU tPDU = response.getResponse();
				if(tPDU == null)
				{
					//System.out.println("get snmp info error, please check community name");
					return "";
				}else{
					tmp = tPDU.toString();
				}
				tmpMap = ProcessRaw(tmp, destOid);
				
				if(tmpMap.get("oid").equals("")) // ��һ��ȡ��ȡ�����е������
				{
					RetStr = RetStr + tmpMap.get("str").toString();
					break;
				}else{
					RetStr = RetStr + tmpMap.get("str").toString();
					pdu.clear();
					OID oids = new OID(tmpMap.get("oid").toString());  //��ѯ����
					pdu.add(new VariableBinding(oids));
				}
			}
			return RetStr;			
		} catch (IOException e) {
			e.printStackTrace();
			return RetStr;
		}
	}
	
	private HashMap<String, String> SortMap(String raw, String oidStr)
	{
		HashMap<String, String> RetMap = new HashMap<String,String>();
		int posEqual = 0; 
		int posEnd = 0; 
		int headPos = oidStr.length()+1;
		String head = null;
		String info = null;
		
		while(raw.length()>0)
		{
			posEqual = raw.indexOf(" = ");
			posEnd  = raw.indexOf(";");
			
			head = raw.substring(headPos, posEqual);
			info = raw.substring(posEqual+3, posEnd);
			RetMap.put(head, info);
			
			if( raw.length() == posEnd+1)
			{
				raw = "";
			}else{
				raw = raw.substring(posEnd + 1);
			}			
		}		
		return RetMap;
	}
	
	public Vector<ADT_dot1dTpFdb> GetInfo(Snmp snmpInstance, String ip, String commu)throws IOException
	{
		communityStr = commu;
		HashMap<String, String> MapStatus;
		HashMap<String, String> MapMAC;
		HashMap<String, String> MapPort;
		
		PDU pdu = new PDU();
		pdu.setType(PDU.GETBULK); // GET GETBULK GETNEXT
		pdu.setMaxRepetitions(MaxRepNum);
		
		OID oids = new OID(dot1dTpFdbAddress);  //��ѯ����
		pdu.add(new VariableBinding(oids));
		String IndexStr = GetSingleInfo(snmpInstance,pdu, ip, dot1dTpFdbAddress);
		MapMAC = SortMap(IndexStr,dot1dTpFdbAddress);

		pdu.clear();
		oids = new OID(dot1dTpFdbPort);
		pdu.add(new VariableBinding(oids));
		IndexStr = GetSingleInfo(snmpInstance,pdu, ip, dot1dTpFdbPort);
		MapPort = SortMap(IndexStr,dot1dTpFdbPort);
		
		pdu.clear();
		oids = new OID(dot1dTpFdbStatus);
		pdu.add(new VariableBinding(oids));
		IndexStr = GetSingleInfo(snmpInstance,pdu, ip, dot1dTpFdbStatus);
		MapStatus = SortMap(IndexStr,dot1dTpFdbStatus);
		
		MakeretVec(MapMAC,MapPort,MapStatus);
		return vecRet;
	}
	
	private void MakeretVec(HashMap<String, String> MapMac_,
							HashMap<String, String> MapPort_,
							HashMap<String, String> MapStatus_)
	{
		vecRet = new Vector<ADT_dot1dTpFdb>();
        Set set = MapMac_.entrySet();   
        Iterator iterator = set.iterator();   
        while(iterator.hasNext())
        {
        	Map.Entry mt = (Map.Entry)iterator.next();
        ADT_dot1dTpFdb item = new ADT_dot1dTpFdb();
        	item.dot1dTpFdbAddress = MapMac_.get(mt.getKey());    
        	item.dot1dTpFdbPort = MapPort_.get(mt.getKey());
        	item.dot1dTpFdbStatus = MapStatus_.get(mt.getKey());    	
        	vecRet.add(item);
        }
	}
}
